package com.blockmeta.bbs.immodule.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.CornerPathEffect;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import com.blockmeta.bbs.baselibrary.utils.DimentionsUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author AirThor
 * @date 2020/6/16.
 *
 * 超导曲线
 */
public class SuperConductivityCurve extends View {
    /**
     * 币币之间的兑换比率 一般为1 可外部传入
     */
    private double mExchangeRate = 1;
    /**
     *  比例浮动范围 此值限制了{@link #mExchangeRate}的最大最小值
     */
    private double mFloatingRange = 0.1;

    /**
     * 币币兑换比率的最小最大值
     * mMinExchangeRate = mExchangeRate - mExchangeRate*mFloatingRange
     * mMaxExchangeRate = mExchangeRate + mExchangeRate*mFloatingRange
     */
    private double mMinExchangeRate,mMaxExchangeRate;
    /**
     * 曲线画笔，滑点保护画笔，当前点画笔，兑换点画笔，曲线下方填充渐变画笔，文字画笔,
     * 坐标系画笔
     */
    private Paint mCurvePaint = new Paint(Paint.ANTI_ALIAS_FLAG)
            ,mProtectDotPaint = new Paint(Paint.ANTI_ALIAS_FLAG)
            ,mCurrentDotPaint = new Paint(Paint.ANTI_ALIAS_FLAG)
            ,mExchangeDotPaint = new Paint(Paint.ANTI_ALIAS_FLAG)
            ,mFillPaint = new Paint()
            ,mTextPaint = new Paint()
            ,mCoordinateSystemPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private Path mLinepath = new Path();
    /**
     * 2dp->px
     */
    private final float DP_2 = DimentionsUtil.dp2px(2);

    /**
     * 被兑换的币名，兑换的币名
     */
    private String mFromCoinName,mToCoinName;

    private int mAxisStep;

    List<SuperConductivityPoint> mPoints = new ArrayList<>();

    public SuperConductivityCurve(Context context) {
        super(context);
    }

    public SuperConductivityCurve(Context context,AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public SuperConductivityCurve(Context context,AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        mCurvePaint.setPathEffect(new CornerPathEffect(50f));
        mCurvePaint.setStyle(Paint.Style.STROKE);
        mCurvePaint.setStrokeWidth(5);
        mCoordinateSystemPaint.setPathEffect(new DashPathEffect(new float[]{5,5},0));
        mCoordinateSystemPaint.setPathEffect(new CornerPathEffect(100f));
        mCoordinateSystemPaint.setStyle(Paint.Style.STROKE);
        mCoordinateSystemPaint.setStrokeWidth(1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //图形宽高一致
        int size = MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(size,size);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mAxisStep = getWidth()/9;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mLinepath.reset();
        canvas.save();
        canvas.translate(0,getHeight());
        for (SuperConductivityPoint point : mPoints) {
            if (point.xPoint == 0){
                mLinepath.moveTo(point.xPoint*mAxisStep,-point.yPoint * mAxisStep);
            }else {
                mLinepath.lineTo(point.xPoint * mAxisStep, -point.yPoint * mAxisStep);
            }
        }
        canvas.drawPath(mLinepath,mCurvePaint);
        canvas.restore();
    }
    public void setParams(long A,long D,long initX,String fromCoinName,String toCoinName,Map<String,Long> xp){
        mPoints.clear();
        mFromCoinName = fromCoinName;
        mToCoinName = toCoinName;


        mAxisStep = getWidth()/9;
        invalidate();
    }
    /**
     * 根据输入参数输出Y值
     * @param A 固定值
     * @param D 固定值
     * @param toCoinName 要换的币的名字
     * @param xp 币名-数量
     * @return y值
     */
    public static long getY(long A, long D, String toCoinName, Map<String, Long> xp) {
        long totalNum = 0;

        int xpLength = xp.size();
        long c = D;

        double ann = A * Math.pow(xpLength, xpLength);
        for (Map.Entry<String, Long> entry : xp.entrySet()) {
            if (!TextUtils.equals(entry.getKey(),toCoinName)) {
                totalNum += entry.getValue();
                c = c * D / (entry.getValue() * xpLength);
            }
        }

        c = (long) (c * D / (ann * xpLength));
        long b = (long) (totalNum + D / ann);
        long y = D;

        long yPrev;
        for (int j = 0; j < 255; j++) {
            yPrev = y;
            y = (y * y + c) / (2 * y + b - D);
            if (y > yPrev && y - yPrev <= 1) {
                break;
            } else if (y <= yPrev && yPrev - y <= 1) {
                break;
            }
        }
        return xp.get(toCoinName)-y;
    }


    public void setExchangeRate(double exchangeRate) {
        mExchangeRate = exchangeRate;
    }

    public void setFloatingRange(double floatingRange) {
        mFloatingRange = floatingRange;
    }

    /**
     * 存放坐标点的类
     */
    private static class SuperConductivityPoint{
        public long xPoint;
        public long yPoint;

        public SuperConductivityPoint(long xPoint, long yPoint) {
            this.xPoint = xPoint;
            this.yPoint = yPoint;
        }
    }

    /**
     * 计算最小最大兑换比值
     */
    private void calculateMinAndMaxRates(){
        mMinExchangeRate = mExchangeRate - mExchangeRate*mFloatingRange;
        mMaxExchangeRate = mExchangeRate + mExchangeRate*mFloatingRange;
    }
}
